import { JOIN_CHAT, CHAT_SYS, LEAVE_CHAT, ROOM_CHAT, MSG_CHAT, SO_DISCONNECT } from '../../const'

/**
  data: {
    type: public | room | private
    user: { userid, username }
    room: { roomid, roomname }
  }
 */

const addUserIfNotExist = (user, users, count) => {
  // 检查在线列表，如果不在里面就加入
  const { userid } = user
  if (!(userid in users)) {
    users[userid] = user
    count.value++
  }
}

const delUserIfExist = (userid, users, count) => {
  // 检查在线列表，如果不在里面就加入
  let user = {}
  if (userid in users) {
    user = users[userid]
    delete users[userid]
    count.value--
  }
  return user
}

const joinChat = (io, socket, opts, data, callback = () => {}) => {
  const { type, user, room } = data
  const { userid } = user
  const msg = { 
    text: ''
  }
  // 获取全局聊天房有关数据
  let { chatPublic, chatRooms, chatPrivate } = opts
  // 将新加入用户的唯一标识当作socket的名称，后面退出的时候会用到
  user.sid = socket.id
  socket.vid = userid
  socket.data = data
  // 检查在线列表，如果不在里面就加入
  addUserIfNotExist(user, chatPublic.users, chatPublic.count)
  if (type === 'public') {
    // 向所有客户端广播用户加入
    const { users, count } = chatPublic
    io.emit(CHAT_SYS, { users, count, user, type })
    // socket.broadcast.emit('users', {})
    // 监听用户发送聊天内容
    socket.on(MSG_CHAT, user => {
      io.emit(MSG_CHAT, user)
      console.log(user.username + '(P)说: ' + user.content)
    })
    msg.text = `${userid} 加入了公共聊天`
    console.log(users)
  } else if (type === 'room') {
    const { roomid, roomname } = room
    const ROOM_ID = `${ROOM_CHAT}:${roomid}`
    // 无聊天房数据时初始化
    if (!(ROOM_ID in chatRooms)) {
      chatRooms[ROOM_ID] = {
        users: {},
        count: {
          value: 0
        }
      }
    } 
    const { users, count } = chatRooms[ROOM_ID]
    addUserIfNotExist(user, users, count)
    // 用户加入房间
    socket.join(ROOM_ID)
    // 回调消息
    msg.text = `${userid} 加入了群聊房间 ${roomid}-${roomname}(${ROOM_ID})`
    io.to(ROOM_ID).emit(CHAT_SYS, { users, count, user, type })
    // 监听用户发送聊天内容
    const MSG_ID = `${MSG_CHAT}:${ROOM_ID}`
    socket.on(MSG_ID, user => {
      io.emit(MSG_ID, user)
      console.log(user.username + '(R)说: ' + user.content)
    })
  } else if (type === 'private') {
    msg.text = `${userid} 加入了私聊房间`
  }
  console.log(msg)
  callback(msg)
}

const leaveChat = (io, socket, opts, data, callback = () => {}) => {
  let { chatPublic, chatRooms, chatPrivate } = opts
  const msg = { text: '' }
  const userid = socket.vid
  // 将退出的用户从在线列表中删除
  const user = delUserIfExist(userid, chatPublic.users, chatPublic.count)
  const { type, room } = data
  if (type === 'public') {
    // 向所有客户端广播用户退出
    const { users, count } = chatPublic
    io.emit(CHAT_SYS, { users, count, user, type})
    msg.text = `${userid} 退出了公共聊天`
  } else if (type === 'room') {
    const { roomid, roomname } = room
    const ROOM_ID = `${ROOM_CHAT}:${roomid}`
    if (!(ROOM_ID in chatRooms)) return
    const { users, count } = chatRooms[ROOM_ID]
    const user = delUserIfExist(userid, users, count)
    if (JSON.stringify(users) === '{}') delete chatRooms[ROOM_ID]
    io.to(ROOM_ID).emit(CHAT_SYS, { users, count, user, type, room })
    socket.leave(ROOM_ID)
    msg.text = `${userid} 退出了群聊房间 ${roomid}-${roomname}(${ROOM_ID})`
  } else if (type === 'private') {
    msg.text = `${userid} 退出了私聊房间`
  } else {
    console.log(`${userid} 断开了私聊房间连接`)
  }
  console.log(msg)
  callback(msg)
}

const disconnectChat = (io, socket, opts) => {
  if (!socket.data.user) return
  const data = socket.data
  leaveChat(io, socket, opts, data)
}

const starListener = (io, socket, opts) => {
  // 监听用户加入聊天房
  socket.on(JOIN_CHAT, (data, callback) => {
    joinChat(io, socket, opts, data, callback)
  })
  // 监听用户退出聊天房
  socket.on(LEAVE_CHAT, (data, callback) => {
    leaveChat(io, socket, opts, data)
  })
  // 监听用户断开连接
  socket.on(SO_DISCONNECT, (data) => {
    disconnectChat(io, socket, opts)
  })
}

export default starListener
